import { GM_xmlhttpRequest, unsafeWindow } from "tm";

unsafeWindow.postDoH = async function postDoH(
  url: string,
  postData?: Uint8Array,
) {
  const timeout = 5000;
  return await (postData
    ? new Promise((resolve, reject) => {
        GM_xmlhttpRequest({
          url,
          nocache: true,
          responseType: "arraybuffer",
          overrideMimeType: "application/dns-message",
          headers: {
            accept: "application/dns-message",
            "Accept-Encoding": "",
            Dnt: "",
            "Sec-Ch-Ua": "",
            "Sec-Ch-Ua-Mobile": "",
            "Sec-Ch-Ua-Platform": "",
            "Sec-Fetch-Dest": "",
            "Sec-Fetch-Mode": "",
            "Sec-Fetch-Site": "",
            "Content-Type": "application/dns-message",
            "User-Agent": "",
          },
          method: "POST",
          data: new Blob([postData]),
          onload(event) {
            resolve({
              status: event.status,
              response: event.response as ArrayBuffer,
            });
          },
          onabort() {
            reject(new Error("abort"));
          },
          onerror() {
            reject(new Error("error"));
          },
          ontimeout() {
            reject(new Error("timeout"));
          },
          timeout,
        });
      })
    : new Promise((resolve, reject) => {
        GM_xmlhttpRequest({
          url,
          responseType: "arraybuffer",
          nocache: true,
          headers: {
            accept: "application/dns-message",
            "Accept-Encoding": "",
            Dnt: "",
            "Sec-Ch-Ua": "",
            "Sec-Ch-Ua-Mobile": "",
            "Sec-Ch-Ua-Platform": "",
            "Sec-Fetch-Dest": "",
            "Sec-Fetch-Mode": "",
            "Sec-Fetch-Site": "",
            "User-Agent": "",
          },
          onload(event) {
            resolve({
              status: event.status,
              response: event.response as ArrayBuffer,
            });
          },
          onabort() {
            reject(new Error("abort"));
          },
          onerror() {
            reject(new Error("error"));
          },
          ontimeout() {
            reject(new Error("timeout"));
          },
          timeout,
        });
      }));
};
